package app.server.project.main.service.db.entity.user;

import app.server.project.core.constants.Def;
import app.server.project.core.syndb.SynDBMgr;
import app.server.project.core.util.MathUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Transient;
import lombok.Data;
import org.hibernate.annotations.Comment;

import java.time.Duration;
import java.time.LocalDateTime;

@Data
@Entity(name = "user_ext")
@TableName("user_ext")
@Comment(value = "用户扩展信息表")
public class UserExtEntity {

    @Id
    @Column(name = "id")
    @Comment("用户主键")
    @TableId("id")
    private long id;

    @TableField("create_time")
    @Comment("创建时间")
    @Column(name = "create_time")
    private LocalDateTime createTime;


    @TableField("invite_num")
    @Comment("邀请aicoin奖励")
    @Column(name = "invite_num")
    private long inviteNum;


    @TableField("share_flag")
    @Comment("分享标志")
    @Column(name = "share_flag")
    private int shareFlag;

    @TableField("share_total")
    @Comment("分享数据累计")
    @Column(name = "share_total")
    private long shareTotal;

    @TableField("race_detail_total")
    @Comment("赛道数据明细数据累计")
    @Column(name = "race_detail_total")
    private long raceDetailTotal;

    @TableField("inner_type")
    @Comment("内部号")
    @Column(name = "inner_type")
    private int innerType;

    @TableField("btc_user_num")
    @Comment("比特币有效用户")
    @Column(name = "btc_user_num")
    private long btcUserNum;

    @TableField("invite_user_num")
    @Comment("邀请用户数量")
    @Column(name = "invite_user_num")
    private long inviteUserNum;

    @TableField("unlock_race_all")
    @Comment("解锁全部赛道")
    @Column(name = "unlock_race_all")
    private int unlockRaceAll;


    @TableField("prop_click_num")
    @Comment("道具点击次数")
    @Column(name = "prop_click_num")
    private long propClickNum;

    @TableField("chance_time")
    @Comment("爆率作用时间")
    @Column(name = "chance_time")
    private LocalDateTime chanceTime;

    @Transient
    @TableField(exist = false)
    private boolean synDb = false;

    public static UserExtEntity of(long userId) {
        UserExtEntity userEnergyEntity = new UserExtEntity();
        userEnergyEntity.setId(userId);
        userEnergyEntity.setSynDb(true);
        userEnergyEntity.setCreateTime(LocalDateTime.now());
        return userEnergyEntity;
    }

    public void addChanceTime(long day) {
        if (this.chanceTime == null) return;
        this.chanceTime = this.chanceTime.plusDays(day);
        this.setChanceTime(this.chanceTime);
    }

    public long getChanceTimeForSeconds() {
        if (this.chanceTime == null) return Def.Zero;
        var time = Duration.between(LocalDateTime.now(), this.chanceTime);
        return time.toSeconds() > Def.Zero ? time.toSeconds() : Def.Zero;
    }

    public void setChanceTime(LocalDateTime chanceTime) {
        this.chanceTime = chanceTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getChanceTime, this);
    }

    public void addPropClickNum(long propClickNum) {
        this.propClickNum += propClickNum;
        this.setPropClickNum(this.propClickNum);
    }

    public void consumePropClickNum() {
        this.propClickNum -= 1;
        this.setPropClickNum(propClickNum);
    }

    public void setPropClickNum(long propClickNum) {
        this.propClickNum = propClickNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getPropClickNum, this);
    }

    public void setUnlockRaceAll(int unlockRaceAll) {
        this.unlockRaceAll = unlockRaceAll;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getUnlockRaceAll, this);
    }

    public void setInviteUserNum(long inviteUserNum) {
        this.inviteUserNum = inviteUserNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getInviteUserNum, this);
    }

    public void setBtcUserNum(long btcUserNum) {
        this.btcUserNum = btcUserNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getBtcUserNum, this);
    }

    public void setInnerType(int inner) {
        this.innerType = inner;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getInnerType, this);
    }

    public void setRaceDetailTotal(long raceDetailTotal) {
        this.raceDetailTotal = raceDetailTotal;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getRaceDetailTotal, this);
    }

    public void setShareTotal(long shareTotal) {
        this.shareTotal = shareTotal;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getShareTotal, this);
    }

    public void setInviteNum(long inviteNum) {
        this.inviteNum = inviteNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getInviteNum, this);
    }

    public void addInviteNum(long num) {
        var ret = MathUtil.canAddNum(this.inviteNum, num);
        if (Def.Zero >= ret) return;
        this.setInviteNum(this.inviteNum + ret);
    }

    public void addInviteUserNum() {
        var ret = MathUtil.canAddNum(this.inviteUserNum, 1);
        if (Def.Zero >= ret) return;
        this.setInviteUserNum(this.inviteUserNum + ret);
    }

    public void addBtcUserNum() {
        var ret = MathUtil.canAddNum(this.btcUserNum, 1);
        if (Def.Zero >= ret) return;
        this.setBtcUserNum(this.btcUserNum + ret);
    }


    public void addShareTotal() {
        this.setShareTotal(this.shareTotal + 1);
    }

    public void addRaceDetailTotal() {
        this.setRaceDetailTotal(this.raceDetailTotal + 1);
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getCreateTime, this);
    }

    public void setShareFlag(int shareFlag) {
        this.shareFlag = shareFlag;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserExtEntity::getShareFlag, this);
    }

}
